<script setup>
import {MAIL_CODE_AGAIN, MAIL_CODE_LEN, MAIL_MAX_LEN, PWD_MAX_LEN, PWD_MIN_LEN} from "@/constants/manager.js"
import {computed, reactive, ref} from "vue"
import {getMailCodeAPI, loginByMailAPI} from "@/api/login.js";

/**
 * 登录信息
 */
const loginInfo = reactive({
  mail: '', // 邮箱
  code: '', // 验证码
  account: '', // 账号/用户名/邮箱
  pwd: '', // 密码
})

/**
 * 邮箱输入自动补全后缀选择选项
 */
const mailIptAutoCompleteOptions = computed(() => {
  return ["@gmail.com", "@163.com", "@qq.com"].map((suffix) => {
    // 获取邮箱 @ 前的输入，由此根据数组项构建全部选择选项
    const prefix = loginInfo.mail.split("@")[0];
    return {
      label: prefix + suffix,
      value: prefix + suffix
    };
  });
})

/**
 * 获取验证码
 */
// 获取验证码按钮是否禁用
const mailCodeBtnDisable = ref(false)
// 获取验证码按钮是否处于加载状态
const mailCodeBtnLoading = ref(false)
// 再次获取验证码所需的时间
const mailCodeAgain = ref(MAIL_CODE_AGAIN + 1)
// 获取验证码按钮文本
const mailCodeBtnText = computed(() => {
  if (mailCodeBtnLoading.value) return '获取验证码中...'
  if (mailCodeAgain.value === MAIL_CODE_AGAIN + 1) return '获取验证码'
  else return `再次获取：${mailCodeAgain.value}s`
})
// 保存计时器，用于计时器的清除
let interval = null

// 获取验证码
async function getMailCode() {
  mailCodeBtnDisable.value = true
  mailCodeBtnLoading.value = true
  // 调用获取验证码 API 发送请求
  getMailCodeAPI(loginInfo.mail).then(
      data => {
        mailCodeBtnLoading.value = false
        // 发生验证码失败
        if (!data) {
          mailCodeBtnDisable.value = false
          return
        }
        mailCodeAgain.value -= 1
        clearInterval(interval)
        interval = setInterval(() => {
          mailCodeAgain.value -= 1
          if (mailCodeAgain.value <= 0) {
            mailCodeAgain.value = MAIL_CODE_AGAIN + 1
            mailCodeBtnDisable.value = false
            clearInterval(interval)
          }
        }, 1000)
      }
  ).catch(
      // 发生验证码发生错误
      () => {
        mailCodeBtnLoading.value = false
        mailCodeBtnDisable.value = false
      }
  )
}

/**
 * 登录按钮是否禁用
 */
const loginByMailBtnDisable = computed(() => {
  return loginInfo.mail.length <= 0 || loginInfo.code.length < MAIL_CODE_LEN
})
const loginByPwdBtnDisable = computed(() => {
  return loginInfo.account.length <= 0 || loginInfo.pwd.length < PWD_MIN_LEN
})

/**
 * 登录
 */
function loginByMail() {
  loginByMailAPI(loginInfo.mail, loginInfo.code)
}

/**
 * 组件卸载前的处理
 */
onBeforeUnmount(() => {
  clearInterval(interval)
})
</script>

<template>
  <div class="login flex-start-center">
    <!-- 轮播图 -->
    <n-carousel
        class="carousel"
        show-arrow
        autoplay
        dot-type="line"
        trigger="hover"
        draggable
    >
      <img
          class="carousel-img"
          src="https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel1.jpeg"
          alt=""
      >
      <img
          class="carousel-img"
          src="https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg"
          alt=""
      >
      <img
          class="carousel-img"
          src="https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel3.jpeg"
          alt=""
      >
      <img
          class="carousel-img"
          src="https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel4.jpeg"
          alt=""
      >
    </n-carousel>
    <!-- 登录表单 -->
    <div class="form-box flex-center">
      <n-card class="form">
        <n-tabs
            class="card-tabs"
            default-value="loginByMail"
            size="large"
            animated
            pane-wrapper-style="margin: 0 -4px"
            pane-style="padding-left: 4px; padding-right: 4px; box-sizing: border-box;"
        >
          <n-tab-pane name="loginByMail" tab="邮箱登录">
            <n-form>
              <n-form-item-row label="邮箱">
                <n-auto-complete
                    v-model:value="loginInfo.mail"
                    :maxlength="MAIL_MAX_LEN"
                    :input-props="{
                    autocomplete: 'disabled'
                  }"
                    :options="mailIptAutoCompleteOptions"
                    placeholder="请输入邮箱"
                    clearable
                />
              </n-form-item-row>
              <n-form-item-row label="验证码">
                <n-input-group>
                  <n-input
                      clearable
                      :maxlength="MAIL_CODE_LEN"
                      :placeholder="`请输入 ${MAIL_CODE_LEN} 验证码`"
                      show-count
                      v-model:value="loginInfo.code"
                  />
                  <n-button
                      type="info"
                      strong
                      :disabled="mailCodeBtnDisable || loginInfo.mail.length <= 0"
                      :loading="mailCodeBtnLoading"
                      @click="getMailCode"
                  >
                    {{ mailCodeBtnText }}
                  </n-button>
                </n-input-group>
              </n-form-item-row>
            </n-form>
            <n-button
                type="info"
                block
                strong
                :disabled="loginByMailBtnDisable"
                @click="loginByMail"
            >
              登录
            </n-button>
          </n-tab-pane>
          <n-tab-pane name="signup" tab="密码登录">
            <n-form>
              <n-form-item-row label="账号/用户名/邮箱">
                <n-input
                    v-model:value="loginInfo.account"
                    :maxlength="MAIL_MAX_LEN"
                    placeholder="请输入账号/用户名/邮箱"
                    clearable
                />
              </n-form-item-row>
              <n-form-item-row label="密码">
                <n-input-group>
                  <n-input
                      clearable
                      :minlength="PWD_MIN_LEN"
                      :maxlength="PWD_MAX_LEN"
                      :placeholder="`请输入密码`"
                      type="password"
                      show-password-on="mousedown"
                      v-model:value="loginInfo.pwd"
                  />
                </n-input-group>
              </n-form-item-row>
            </n-form>
            <n-button
                type="info"
                block
                strong
                :disabled="loginByPwdBtnDisable"
            >
              登录
            </n-button>
          </n-tab-pane>
        </n-tabs>
      </n-card>
    </div>
  </div>
</template>

<style scoped lang="scss">
.login {
  width: 100%;
  height: calc(100vh - var(--top-nav-height));

  // 轮播图
  .carousel {
    //width: 40rem;
    //height: 25rem;
    width: 60%;
    height: 100%;
    border-top-right-radius: 3rem;

    // 轮播图图片
    .carousel-img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }

  // 表单盒子
  .form-box {
    flex: 1;

    // 表单
    .form {
      width: 30rem;
      height: 25rem;
    }
  }
}
</style>